<?php


namespace App\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

use Hyperf\Utils\Context;
use Hyperf\Di\Annotation\AnnotationCollector;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Mapping;
use Hyperf\HttpServer\Annotation\PatchMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Router\Dispatched;

class RouteListDebugMiddleware implements MiddlewareInterface {

    public function process (ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {

        $request = Context::set(ServerRequestInterface::class, $request);

        /** @var Dispatched $dispatched */
        $dispatched = $request->getAttribute(Dispatched::class);

        // var_dump($dispatched);
        // var_dump(Dispatched::class);
        //
        // exit();

        $collector = AnnotationCollector::list();

        $mappingAnnotations = [
            RequestMapping::class,
            GetMapping::class,
            PostMapping::class,
            PutMapping::class,
            PatchMapping::class,
            DeleteMapping::class,
        ];

        // var_dump($collector);

        $routeList = [];

        foreach ($collector as $className => $metadata) {

            if (isset($metadata['_c']) && isset($metadata['_c'][Controller::class])) {

                /** @var Controller $controller */
                $controller = $metadata['_c'][Controller::class];
                $prefix     = $controller->prefix;

                $methodList = isset($metadata['_m']) ? $metadata['_m'] : [];


                foreach ($methodList as $methodName => $values) {
                    foreach ($mappingAnnotations as $mappingAnnotation) {

                        /** @var Mapping $mapping */
                        if ($mapping = $values[$mappingAnnotation] ?? null) {
                            if (!isset($mapping->path) || !isset($mapping->methods) || !isset($mapping->options)) {
                                continue;
                            }

                            $path = $mapping->path;

                            if ($path === '') {
                                $path = $prefix;
                            }
                            else if ($path[0] !== '/') {
                                $path = $prefix.'/'.$path;
                            }

                            array_push($routeList, $path);
                        }
                    }
                }
            }
        }

        $address     = sprintf('%s://%s:%s%s', $request->getUri()->getScheme(), $request->getUri()->getHost(), $request->getUri()->getPort(), $request->getUri()->getPath());
        $requestPath = $request->getUri()->getPath();

        $debug = [
            'routeList'   => $routeList,
            'address'     => $address,
            'requestPath' => $requestPath,
            'isMatch'     => in_array($requestPath, $routeList) ? 'true' : 'false',
        ];

//        var_dump($debug);

        return $handler->handle($request);
    }
}
